const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const compression = require('compression');
const path = require('path');
require('dotenv').config();

// 导入路由
const publicRoutes = require('./routes/public');
const adminRoutes = require('./routes/admin');
const smsRoutes = require('./routes/sms');

// 导入数据库
const { testConnection } = require('./config/database');

const app = express();
const PORT = process.env.PORT || 3000;

// =================== 中间件配置 ===================

// 安全头部
app.use(helmet({
  crossOriginResourcePolicy: { policy: "cross-origin" },
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'", "data:", "http://cdn.jsdelivr.net", "https://cdn.jsdelivr.net"],
      styleSrc: ["'self'", "'unsafe-inline'", "data:", "http://cdn.jsdelivr.net", "https://cdn.jsdelivr.net"],
      fontSrc: ["'self'", "http://cdn.jsdelivr.net", "https://cdn.jsdelivr.net"],
      connectSrc: ["'self'"],
      imgSrc: ["'self'", "data:", "http:", "https:"],
    },
  }
}));

// 跨域配置
const allowedOrigins = [
  'http://localhost:3000',
  'http://127.0.0.1:3000',
  'http://localhost:3001',
  'http://localhost:8080',
  'http://127.0.0.1:8080',
  'http://127.0.0.1:5500',
  'http://hunaction.com',
  'https://hunaction.com',
  'http://admin.hunaction.com',
  'https://admin.hunaction.com',
];
const allowedOriginPatterns = [
  /^https?:\/\/.*\.oicp\.vip$/,
  /^https?:\/\/.*\.ngrok\.io$/,
  /^https?:\/\/.*\.tunnel\..*$/
];
app.use((req, res, next) => {
  // 处理 OPTIONS 预检请求
  if (req.method === 'OPTIONS') {
    res.header('Access-Control-Allow-Origin', req.headers.origin || '*');
    res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Content-Type,Authorization,X-Requested-With');
    res.header('Access-Control-Allow-Credentials', 'true');
    return res.sendStatus(204);
  }
  next();
});
app.use(cors({
  origin: function(origin, callback) {
    if (!origin) return callback(null, true); // 允许非浏览器请求
    if (allowedOrigins.includes(origin)) return callback(null, true);
    if (allowedOriginPatterns.some(pattern => pattern.test(origin))) return callback(null, true);
    return callback(new Error('Not allowed by CORS: ' + origin));
  },
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With']
}));

// 请求日志
if (process.env.NODE_ENV !== 'test') {
  app.use(morgan('combined'));
}

// 压缩
app.use(compression());

// 解析请求体
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));

// 静态文件服务（上传的附件）
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));

// 根路径静态文件服务（调试页面等）
app.use(express.static(path.join(__dirname, 'public')));

// 管理页面静态文件服务
app.use('/admin', (req, res, next) => {
  // 为管理页面禁用CSP，允许内联JavaScript
  res.removeHeader('Content-Security-Policy');
  res.removeHeader('Content-Security-Policy-Report-Only');
  next();
}, express.static(path.join(__dirname, 'public/admin')));

// 设置请求IP
app.use((req, res, next) => {
  req.ip = req.headers['x-forwarded-for'] ||
           req.headers['x-real-ip'] ||
           req.connection.remoteAddress ||
           req.socket.remoteAddress ||
           (req.connection.socket ? req.connection.socket.remoteAddress : null);
  next();
});

// =================== 路由配置 ===================

// API 根路径
app.get('/', (req, res) => {
  res.json({
    code: 200,
    message: '百日行动线索收集系统 API',
    version: '1.0.0',
    timestamp: Date.now()
  });
});

// 健康检查
app.get('/health', async (req, res) => {
  try {
    const dbStatus = await testConnection();
    res.json({
      code: 200,
      message: 'OK',
      data: {
        server: 'running',
        database: dbStatus ? 'connected' : 'disconnected',
        timestamp: new Date().toISOString()
      }
    });
  } catch (error) {
    res.status(503).json({
      code: 503,
      message: 'Service Unavailable',
      data: {
        server: 'running',
        database: 'error',
        timestamp: new Date().toISOString()
      }
    });
  }
});

// 公开API路由
app.use('/api', publicRoutes);

// 短信API路由
app.use('/api', smsRoutes);

// 管理员API路由
app.use('/api/admin', adminRoutes);

// 管理页面路由重定向
app.get('/admin/', (req, res) => {
  res.redirect('/admin/login.html');
});

// =================== 错误处理 ===================

// 404错误处理
app.use('*', (req, res) => {
  res.status(404).json({
    code: 404,
    message: 'API接口不存在',
    path: req.originalUrl,
    timestamp: Date.now()
  });
});

// 全局错误处理中间件
app.use((error, req, res, next) => {
  console.error('服务器错误:', error);

  // Multer文件上传错误
  if (error.code === 'LIMIT_FILE_SIZE') {
    return res.status(400).json({
      code: 400,
      message: '文件大小超过限制',
      timestamp: Date.now()
    });
  }

  if (error.code === 'LIMIT_FILE_COUNT') {
    return res.status(400).json({
      code: 400,
      message: '文件数量超过限制',
      timestamp: Date.now()
    });
  }

  if (error.message === '不支持的文件类型') {
    return res.status(400).json({
      code: 400,
      message: '不支持的文件类型',
      timestamp: Date.now()
    });
  }

  // 数据库错误
  if (error.code === 'ER_DUP_ENTRY') {
    return res.status(400).json({
      code: 400,
      message: '数据已存在',
      timestamp: Date.now()
    });
  }

  if (error.code === 'ER_NO_REFERENCED_ROW_2') {
    return res.status(400).json({
      code: 400,
      message: '引用的数据不存在',
      timestamp: Date.now()
    });
  }

  // JWT错误
  if (error.name === 'JsonWebTokenError') {
    return res.status(401).json({
      code: 401,
      message: '无效的认证令牌',
      timestamp: Date.now()
    });
  }

  if (error.name === 'TokenExpiredError') {
    return res.status(401).json({
      code: 401,
      message: '认证令牌已过期',
      timestamp: Date.now()
    });
  }

  // 参数验证错误
  if (error.type === 'entity.parse.failed') {
    return res.status(400).json({
      code: 400,
      message: '请求数据格式错误',
      timestamp: Date.now()
    });
  }

  // 默认服务器错误
  res.status(500).json({
    code: 500,
    message: process.env.NODE_ENV === 'production' ? '服务器内部错误' : error.message,
    timestamp: Date.now()
  });
});

// =================== 服务器启动 ===================

async function startServer() {
  try {
    // 测试数据库连接
    console.log('🔗 正在连接数据库...');
    const dbConnected = await testConnection();

    if (!dbConnected) {
      console.error('❌ 数据库连接失败，服务器启动中止');
      process.exit(1);
    }

    // 启动服务器
    const server = app.listen(PORT, () => {
      console.log('🚀 服务器启动成功!');
      console.log(`📡 服务器地址: http://localhost:${PORT}`);
      console.log(`🌍 环境: ${process.env.NODE_ENV || 'development'}`);
      console.log(`📊 API文档: http://localhost:${PORT}/api`);
      console.log('⏰ 启动时间:', new Date().toLocaleString());
      console.log('=' .repeat(50));
    });

    // 优雅关闭
    process.on('SIGTERM', () => {
      console.log('🛑 收到SIGTERM信号，开始优雅关闭...');
      server.close(() => {
        console.log('✅ 服务器已关闭');
        process.exit(0);
      });
    });

    process.on('SIGINT', () => {
      console.log('🛑 收到SIGINT信号，开始优雅关闭...');
      server.close(() => {
        console.log('✅ 服务器已关闭');
        process.exit(0);
      });
    });

  } catch (error) {
    console.error('❌ 服务器启动失败:', error);
    process.exit(1);
  }
}

// 启动服务器
if (require.main === module) {
  startServer();
}

module.exports = app;
